package com.mashuai.utils.toolkit.core.msHandlebean;

import com.mashuai.utils.base.MsAssertUtils;
import com.mashuai.utils.base.MsIocUtils;
import com.mashuai.utils.toolkit.achieve.HandleDataUtilsCore;
import com.mashuai.utils.toolkit.achieve.MsExegesis;
import com.mashuai.utils.toolkit.core.msHandlebean.dto.MsDelCheckDto;
import com.mashuai.utils.toolkit.core.msHandlebean.dto.MsDictDto;
import com.mashuai.utils.toolkit.core.msHandlebean.dto.MsSaveCheckDto;
import com.mashuai.utils.toolkit.inter.functionalInterface.handleBean.FMsSelfHandleBean;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author: mashuai
 * @ClassName: MsHandleDataUtils
 * @Description: 处理工具类
 */
@MsExegesis("com.mashuai.toolkit.core.msHandlebean.annotation包下注解都必须手动调用对应其方法")
public class MsHandleDataUtils implements Serializable {

    private static HandleDataUtilsCore handleDataUtilsCore = MsIocUtils.getBean(HandleDataUtilsCore.class);

    /**
     * 获取字典值：实现方式由用户自己实现。
     **/
    @MsExegesis("获取字典值：实现方式由用户自己实现IMsGetDict接口")
    public static Map<String, List<MsDictDto>> getDictData(List<String> dictTypeList) {
        return handleDataUtilsCore.getDictData(dictTypeList);
    }

    /**
     * 处理表关系、字典映射
     *
     * @param m     实体类
     * @param clazz 实体类 类对象
     * @return
     * @author mashuai
     */
    @MsExegesis("处理表关系、字典映射。m@实体类；clazz@实体类类对象")
    public static <M> void handleTbOrDictValBeans(M m, Class<M> clazz) {
        if (null != m) handleTbOrDictValBeans(Arrays.asList(m), clazz);
    }

    /**
     * 增加对bean的自定义处理。
     **/
    @MsExegesis("增加对bean的自定义处理")
    public static <M> void handleTbOrDictValBeans(M m, Class<M> clazz, FMsSelfHandleBean<M> selfHandleBean) {
        if (null != m) {
            handleTbOrDictValBeansM(Arrays.asList(m), clazz, selfHandleBean, null, null);
        }
    }

    @MsExegesis("增加一些需要排除数据处理的注解")
    public static <M> void handleTbOrDictValBeans(M m, Class<M> clazz, List<Class<? extends Annotation>> excludedAnnotations) {
        if (null != m) {
            handleTbOrDictValBeansM(Arrays.asList(m), clazz, null, excludedAnnotations, null);
        }
    }

    @MsExegesis("增加一些需要排除数据处处理的字段名称")
    public static <M> void handleTbOrDictValBeans(M m, Class<M> clazz, String excludedFiledNames) {
        if (null != m) {
            handleTbOrDictValBeansM(Arrays.asList(m), clazz, null, null, excludedFiledNames);
        }
    }


    /**
     * 处理集合
     **/
    public static <M> void handleTbOrDictValBeans(List<M> list, Class<M> clazz) {
        handleTbOrDictValBeansM(list, clazz, null, null, null);
    }

    public static <M> void handleTbOrDictValBeans(List<M> list, Class<M> clazz, FMsSelfHandleBean<M> selfHandleBean) {
        handleTbOrDictValBeansM(list, clazz, selfHandleBean, null, null);
    }


    public static <M> void handleTbOrDictValBeans(List<M> list, Class<M> clazz, List<Class<? extends Annotation>> excludedAnnotations) {
        handleTbOrDictValBeansM(list, clazz, null, excludedAnnotations, null);
    }

    public static <M> void handleTbOrDictValBeans(List<M> list, Class<M> clazz, String excludedFiledNames) {
        handleTbOrDictValBeansM(list, clazz, null, null, excludedFiledNames);
    }

    private static <M> void handleTbOrDictValBeansM(List<M> list, Class<M> clazz, FMsSelfHandleBean<M> selfHandleBean, List<Class<? extends Annotation>> excludedAnnotations, String excludedFiledNames) {
        handleDataUtilsCore.handleTbOrDictValBeansM(list, clazz, selfHandleBean, excludedAnnotations, excludedFiledNames);
    }

    /**
     * 保存数据时候，检验字段值是否存在
     * 因涉及到数据回滚操作，这边把异常抛出在方法上throws Exception
     *
     * @param m
     * @param throwException true，直接抛出异常
     * @return
     * @author mashuai
     */
    @MsExegesis("保存数据时候，检验字段值是否存在")
    public static <T> List<MsSaveCheckDto> handleSaveCheck(T m, boolean throwException) {
        try {
            return handleDataUtilsCore.handleSaveCheckM(m, throwException);
        } catch (Exception e) {
            MsAssertUtils.throwException(e.getMessage());
            return null;
        }
    }

    public static <M> void handleSaveCheck(M m) {
        try {
            handleDataUtilsCore.handleSaveCheckM(m, true);
        } catch (Exception e) {
            MsAssertUtils.throwException(e.getMessage());
        }
    }

    /**
     * 检验删除的数据是否被其他表进行引用了
     *
     * @param list           删除的数据集合，一般是List<Id>，如果throwException=false，会把可以删除的id进行返回x
     * @param clazz          类型对象
     * @param throwException 当存在被引用的数据时候，是否抛出异常
     * @return 如果throwException=false，具体不能删除的数据，在 List<MsDelCheckDto>，根据业务自己拼接提示即可
     * @author mashuai
     */
    @MsExegesis("检验删除的数据是否被其他表进行引用了")
    public static <M, S> List<MsDelCheckDto> handleDelCheck(List<S> list, Class<M> clazz, boolean throwException) {
        return handleDataUtilsCore.handleDelCheckM(list, clazz, throwException);
    }

    public static <M, S> List<MsDelCheckDto> handleDelCheck(List<S> list, Class<M> clazz) {
        return handleDataUtilsCore.handleDelCheckM(list, clazz, true);
    }


    /**
     * 把一组List<T>数据变成，下拉框值。
     *
     * @param list
     * @param entityClazz
     * @return
     * @author mashuai
     */
    @MsExegesis("把一组List<T>数据变成，下拉框值。前提使用@MsTbForderField注解")
    public static <T> List<Map<String, Object>> handleTbDictSelect(List<T> list, Class<T> entityClazz) {
        return handleDataUtilsCore.handleTbDictSelect(list, entityClazz);
    }


}
